package leetcode;

import java.util.ArrayDeque;
import java.util.Deque;

/**
 * @创建人 MBY381
 * @创建时间 2022/4/18 12:10
 * @描述 给你一个 n x n 的二进制矩阵 grid 中，返回矩阵中最短 畅通路径 的长度。如果不存在这样的路径，返回 -1 。
 * <p>
 * 二进制矩阵中的 畅通路径 是一条从 左上角 单元格（即，(0, 0)）到 右下角 单元格（即，(n - 1, n - 1)）的路径，该路径同时满足下述要求：
 * <p>
 * 路径途经的所有单元格都的值都是 0 。
 * 路径中所有相邻的单元格应当在 8 个方向之一 上连通（即，相邻两单元之间彼此不同且共享一条边或者一个角）。
 * 畅通路径的长度 是该路径途经的单元格总数。
 */
public class Solution1091 {
    static class Node {
        int x;
        int y;
        int step;

        public Node(int start, int end, int step) {
            this.x = start;
            this.y = end;
            this.step = step;
        }
    }

//    int[] dx = {0, 0, -1, 1, -1, 1, -1, 1};
//    int[] dy = {-1, 1, 0, 0, -1, -1, 1, 1};

    public int shortestPathBinaryMatrix(int[][] grid) {

        Node node = new Node(0, 0, 2);
        Deque<Node> queue = new ArrayDeque<>();
        queue.addLast(node);
        int[][] direction=new int[][]{{1,1},{1,0},{0,1},{-1,1},{1,-1},{-1,0},{0,-1},{-1,-1}};
        int n = grid.length;
        if (grid[0][0] == 1 || grid[n - 1][n - 1] == 1) {
            return -1;
        } else if (n <= 2) {
            return n;
        }
        while (!queue.isEmpty()) {
            Node cur = queue.poll();
            int x = cur.x;
            int y = cur.y;
            int step = cur.step;
            for (int i = 0; i < 8; i++) {
                int newX = x + direction[i][0];
                int newY = y + direction[i][1];
                if (newX>=0 && newX < n && newY>=0 && newY < n && grid[newX][newY] == 0) {
                    //找到终点
                    if (newX == n - 1 && newY == n - 1) {
                        return step;
                    }
                    queue.addLast(new Node(newX, newY, step + 1));
                    grid[newX][newY] = 1; //标记已遍历过，避免重复
                }
            }
        }
        return -1;
    }
}
